package org.sunrise.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.ScreenUtils;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.scenes.scene2d.Actor;
import org.sunrise.game.client.client.PlayerInfo;
import org.sunrise.game.client.client.SocketClient;
import org.sunrise.game.client.client.SocketClientManager;
import org.sunrise.game.client.gen.ChatProto;
import org.sunrise.game.client.gen.LoginProto;
import org.sunrise.game.client.gen.MapProto;
import org.sunrise.game.client.gen.TopicProto;
import org.sunrise.game.client.main.LoginManager;
import org.sunrise.game.common.utils.Utils;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

public class ClientStartUp extends ApplicationAdapter {
    private static final int SCREEN_WIDTH = 1366;
    private static final int SCREEN_HEIGHT = 768;
    private Stage stage;
    private Skin skin;
    private boolean gameStarted = false;
    public static String myHumanId = null;
    private TextField uidField;
    private TextButton loginButton;
    private Texture loginBackground; // 登录背景和玩家贴图
    private SpriteBatch batch;
    private float moveSpeed = 100f; // 移动速度

    public static Map<String, PlayerInfo> otherPlayers = new ConcurrentHashMap<>(); // 存储其他玩家的信息
    @Override
    public void create() {
        stage = new Stage(new FitViewport(SCREEN_WIDTH, SCREEN_HEIGHT));
        skin = new Skin(Gdx.files.internal("ui/uiskin.json"));

        // 加载资源
        batch = new SpriteBatch();
        loginBackground = new Texture(Gdx.files.internal("game_background.png")); // 登录背景
        setupUI();

        SocketClientManager.socketType = "websocket";
    }

    private void setupUI() {
        float centerX = SCREEN_WIDTH / 2f;
        float centerY = SCREEN_HEIGHT / 2f;

        uidField = new TextField("", skin);
        uidField.setMessageText("请输入 UID");
        uidField.setSize(300, 50);
        uidField.setPosition(centerX - 150, centerY + 30);

        loginButton = new TextButton("登录", skin);
        loginButton.setSize(150, 50);
        loginButton.setPosition(centerX - 75, centerY - 40);
        loginButton.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                String uid = uidField.getText();
                if (!uid.isEmpty()) {
                    gameStarted = true;

                    login(uid);
                    showGameScreen();
                }
            }
        });

        stage.addActor(uidField);
        stage.addActor(loginButton);
        Gdx.input.setInputProcessor(stage);
    }

    private void login(String uid) {
        SocketClient client = SocketClientManager.getInstance();

        client.initHttp();
        client.setUid(uid);
        LoginManager.login(client);
        while (true) {
            if (client.isStartSend()) {
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        // 定时ping
        new Thread(() -> {
            while (true) {
                client.sendMsg(TopicProto.MBasePacketData.newBuilder()
                    .setPacketType(TopicProto.TOPIC.TOPIC_TYPE_LOGIN)
                    .setPacketId(LoginProto.FROM_CLIENT.C2S_ClientPing_VALUE)
                    .build());
                client.setPingStartTime(System.currentTimeMillis());
                client.setSendCount(client.getSendCount() + 1);
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();

        client.sendMsg(TopicProto.MBasePacketData.newBuilder()
            .setPacketType(TopicProto.TOPIC.TOPIC_TYPE_MAP)
            .setPacketId(MapProto.FROM_CLIENT.C2S_Enter_VALUE)
            .setPacketData(MapProto.MC2S_Enter.newBuilder().setId(1).build().toByteString()) // 假设进入地图ID为1
            .build());

        client.sendMsg(TopicProto.MBasePacketData.newBuilder()
            .setPacketType(TopicProto.TOPIC.TOPIC_TYPE_CHAT)
            .setPacketId(ChatProto.FROM_CLIENT.C2S_Chat_VALUE)
            .setPacketData(ChatProto.MC2S_Chat.newBuilder().setType(1).setMsg("hhhhhhhhh" + client.getUid()).build().toByteString())
            .build());
        Random random = new Random();
        new Thread(() -> {
            while (true) {
                PlayerInfo playerInfo = otherPlayers.get(myHumanId);
                if (playerInfo != null) {
                    int targetX = random.nextInt(SCREEN_WIDTH);
                    int targetY = random.nextInt(SCREEN_HEIGHT);
                    playerInfo.setTargetPosition(targetX, targetY);
                    move(targetX, targetY);
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();

        Utils.setShutdownHook(() -> {
            client.sendMsg(TopicProto.MBasePacketData.newBuilder()
                .setPacketType(TopicProto.TOPIC.TOPIC_TYPE_MAP)
                .setPacketId(MapProto.FROM_CLIENT.C2S_Leave_VALUE)
                .setPacketData(MapProto.MC2S_Leave.newBuilder().setId(1).build().toByteString())
                .build());
        });
    }

    private void showGameScreen() {
        stage.clear(); // 只清理 UI，背景和角色仍由 batch 渲染
    }

    private void updateMyPosition() {
        float deltaTime = Gdx.graphics.getDeltaTime();

        if (myHumanId == null) {
            return;
        }
        PlayerInfo playerInfo = otherPlayers.get(myHumanId);
        if (playerInfo == null) {
            return;
        }

        // 处理鼠标点击（更新目标位置）
        if (Gdx.input.justTouched()) {
            int targetX = Gdx.input.getX();
            int targetY = SCREEN_HEIGHT - Gdx.input.getY();
            playerInfo.setTargetPosition(targetX, targetY);
            move(targetX, targetY);
        }

        // 计算方向向量并归一化
        Vector2 direction = new Vector2(playerInfo.getTargetPos()).sub(playerInfo.getPlayerPos());
        if (direction.len() > 1f) { // 防止抖动
            direction.nor().scl(moveSpeed * deltaTime);
            playerInfo.getPlayerPos().add(direction);
        }
    }

    private void move(int targetX, int targetY) {
        MapProto.MC2S_Move moveData = MapProto.MC2S_Move.newBuilder()
            .setMapPostX(targetX)
            .setMapPostY(targetY)
            .build();

        SocketClientManager.getInstance().sendMsg(TopicProto.MBasePacketData.newBuilder()
            .setPacketType(TopicProto.TOPIC.TOPIC_TYPE_MAP)
            .setPacketId(MapProto.FROM_CLIENT.C2S_Move_VALUE)
            .setPacketData(moveData.toByteString())
            .build());
    }

    @Override
    public void render() {
        ScreenUtils.clear(1f, 1f, 1f, 1f);
        if (gameStarted) {
            updateMyPosition();
            for (PlayerInfo player : otherPlayers.values()) {
                player.updatePosition(Gdx.graphics.getDeltaTime());
            }

        } else {
            batch.begin();
            batch.draw(loginBackground, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
            batch.end();
        }
        stage.act(Gdx.graphics.getDeltaTime());
        stage.draw();
    }

    @Override
    public void resize(int width, int height) {
        stage.getViewport().update(width, height, true);
    }

    @Override
    public void dispose() {
        stage.dispose();
        skin.dispose();
        loginBackground.dispose();
        System.exit(0);
    }
}
